package cn.com.hatech.blog.module.admin.category.service.impl;

import cn.com.hatech.blog.common.constant.Types;
import cn.com.hatech.blog.common.exception.TipException;
import cn.com.hatech.blog.module.admin.article.entity.ArticleMeta;
import cn.com.hatech.blog.module.admin.article.mapper.ArticleMetaMapper;
import cn.com.hatech.blog.module.admin.category.entity.Meta;
import cn.com.hatech.blog.module.admin.category.mapper.MetaMapper;
import cn.com.hatech.blog.module.admin.category.service.IMetaService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @projectName: hatech-blog
 * @package: cn.com.hatech.blog.module.admin.service.impl
 * @className: MetaServiceImpl
 * @author: xuruikai
 * @description: 分类信息业务层接口实现
 * @date: 2020/1/11 14:27
 * @version: 1.0
 */
@Slf4j
@Service("metaService")
public class MetaServiceImpl implements IMetaService {

    @Resource
    private MetaMapper metaMapper;

    @Resource
    private ArticleMetaMapper contentMetaMapper;

    @Override
    public List<Meta> selectAllMetas() {
        List<Meta> metas = this.metaMapper.selectList(null);
        // 设置包含文章数量
        return metas.stream().map(meta -> this.setContentCountForMeta(meta)).collect(Collectors.toList());
    }

    @Override
    public void saveMeta(String type, String name, String id) {
        if (StringUtils.isEmpty(type) || StringUtils.isEmpty(name)) {
            throw new TipException("分类参数异常,保存失败");
        }
        // TODO sql优化
        QueryWrapper<Meta> metaQueryWrapper = new QueryWrapper<>();

        metaQueryWrapper
                .lambda()
                .eq(Meta::getType, type)
                .eq(Meta::getName, name);

        if (StringUtils.isNotEmpty(id)) {
            metaQueryWrapper.lambda().ne(Meta::getId, id);
        }
        int count = metaMapper.selectCount(metaQueryWrapper);

        if (count > 0) {
            throw new TipException("该分类已存在");
        }

        Meta metas = Meta.builder().name(name).build();
        if (StringUtils.isNotEmpty(id)) {
            metas.setId(id);
            metaMapper.updateById(metas);
        } else {
            metas.setType(type);
            metaMapper.insert(metas);
        }

    }

    @Override
    public List<Meta> selectAllMetasByType(String types) {
        if (StringUtils.isEmpty(types)) {
            return null;
        }
        QueryWrapper<Meta> metaQueryWrapper = new QueryWrapper<>();
        metaQueryWrapper.lambda().eq(Meta::getType, types);
        metaQueryWrapper.orderByDesc("sort");
        return this.metaMapper.selectList(metaQueryWrapper);
    }

    @Override
    public Meta getMeta(String type, String name) {
        if (StringUtils.isEmpty(type) || StringUtils.isEmpty(name)) {
            return null;
        }
        QueryWrapper<Meta> metaQueryWrapper = new QueryWrapper<>();
        metaQueryWrapper.lambda().eq(Meta::getType, type).eq(Meta::getName, name);
        Meta meta = metaMapper.selectOne(metaQueryWrapper);
        // TODO 处理关联文章数量
        this.setContentCountForMeta(meta);
        return meta;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        Meta metas = metaMapper.selectById(id);
        if (null == metas) {
            throw new TipException("分类不存在,删除失败");
        }
        // 删除分类
        metaMapper.deleteById(id);
        // 删除关联数据
        UpdateWrapper<ArticleMeta> contentMetaUpdateWrapper = new UpdateWrapper<>();
        contentMetaUpdateWrapper.lambda().eq(ArticleMeta::getMetaId, id);
        this.contentMetaMapper.delete(contentMetaUpdateWrapper);
    }

    @Override
    public String getMetaNamesByMetaIds(List<String> metaIds, String type) {
        if (null == metaIds || metaIds.isEmpty()) {
            return null;
        }
        // 查询所有分类
        QueryWrapper<Meta> metaQueryWrapper = new QueryWrapper<>();
        metaQueryWrapper.lambda().in(Meta::getId, metaIds);
        return this.getMetaNamesByMetaList(this.metaMapper.selectList(metaQueryWrapper), type);
    }

    /**
     * 批量处理文章 发布/编辑时 关联的分类数据
     *
     * @param id
     * @param categoryNames
     * @param tagNames
     */
    @Override
    public int saveMetas(String id, String categoryNames, String tagNames) {
        if (StringUtils.isEmpty(id)) {
            throw new TipException("文章id为空,分类数据处理失败");
        }
        // 移除文章现有的分类数据
        UpdateWrapper<ArticleMeta> contentMetaUpdateWrapper = new UpdateWrapper<>();
        contentMetaUpdateWrapper.lambda().eq(ArticleMeta::getArticleId, id);
        contentMetaMapper.delete(contentMetaUpdateWrapper);
        // 获取分类名称数组
        String[] categoryNameArray = StringUtils.split(categoryNames, ",");
        List<ArticleMeta> contentMetas = Arrays.asList(categoryNameArray).stream().map(categoryName -> {
            QueryWrapper<Meta> metaQueryWrapper = new QueryWrapper<>();
            metaQueryWrapper.lambda().eq(Meta::getName, categoryName).eq(Meta::getType, Types.CATEGORY.getType());
            Meta meta = this.metaMapper.selectOne(metaQueryWrapper);
            ArticleMeta contentMeta = new ArticleMeta();
            contentMeta.setArticleId(id);
            contentMeta.setMetaId(meta.getId());
            return contentMeta;
        }).collect(Collectors.toList());
        // TODO 需要改成批量新增
        contentMetas.forEach(contentMeta -> this.contentMetaMapper.insert(contentMeta));
        // 获取标签名称数据
        String[] tagNameArray = StringUtils.split(tagNames, ",");
        List<ArticleMeta> contentMetas2 = Arrays.asList(tagNameArray).stream().map(tagName -> {
            QueryWrapper<Meta> metaQueryWrapper = new QueryWrapper<>();
            metaQueryWrapper.lambda().eq(Meta::getName, tagName).eq(Meta::getType, Types.TAG.getType());
            Meta meta = this.metaMapper.selectOne(metaQueryWrapper);
            if (meta == null) {
                meta = new Meta();
                meta.setName(tagName);
                meta.setType(Types.TAG.getType());
                this.metaMapper.insert(meta);
            }
            ArticleMeta contentMeta = new ArticleMeta();
            contentMeta.setArticleId(id);
            contentMeta.setMetaId(meta.getId());
            return contentMeta;
        }).collect(Collectors.toList());
        // TODO 需要改成批量新增 优先级高
        contentMetas2.forEach(contentMeta -> this.contentMetaMapper.insert(contentMeta));
        return 1;
    }

    /**
     * 跟分类附上关联文章数量的值
     *
     * @param meta
     */
    private Meta setContentCountForMeta(Meta meta) {
        QueryWrapper<ArticleMeta> contentMetaQueryWrapper = new QueryWrapper<>();
        contentMetaQueryWrapper.lambda().eq(ArticleMeta::getMetaId, meta.getId());
        int count = this.contentMetaMapper.selectCount(contentMetaQueryWrapper);
        meta.setCount(count);
        return meta;
    }

    /**
     * 通过分类标签类型进行筛选,并转换为名称集合字符串,用逗号隔开
     *
     * @param metas
     * @param type
     * @return
     */
    private String getMetaNamesByMetaList(List<Meta> metas, String type) {
        return metas.stream()
                // 根据分类标签类型筛选
                .filter(meta -> type.equals(meta.getType()))
                // 提取名称
                .map(Meta::getName)
                // 转换为数据字符串
                .collect(Collectors.joining(","));
    }
}
